<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Detailed features description</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="Chapter 1. Boost.Log v2">
<link rel="up" href="../index.html" title="Chapter 1. Boost.Log v2">
<link rel="prev" href="tutorial/wide_char.html" title="Wide character logging">
<link rel="next" href="detailed/sources.html" title="Logging sources">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutorial/wide_char.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="detailed/sources.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="log.detailed"></a><a class="link" href="detailed.html" title="Detailed features description">Detailed features description</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="detailed.html#log.detailed.core">Core facilities</a></span></dt>
<dt><span class="section"><a href="detailed/sources.html">Logging sources</a></span></dt>
<dt><span class="section"><a href="detailed/sink_frontends.html">Sink frontends</a></span></dt>
<dt><span class="section"><a href="detailed/sink_backends.html">Sink backends</a></span></dt>
<dt><span class="section"><a href="detailed/expressions.html">Lambda expressions</a></span></dt>
<dt><span class="section"><a href="detailed/attributes.html">Attributes</a></span></dt>
<dt><span class="section"><a href="detailed/utilities.html">Utilities</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="log.detailed.core"></a><a class="link" href="detailed.html#log.detailed.core" title="Core facilities">Core facilities</a>
</h3></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="detailed.html#log.detailed.core.record">Logging records</a></span></dt>
<dt><span class="section"><a href="detailed.html#log.detailed.core.core">Logging core</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="log.detailed.core.record"></a><a class="link" href="detailed.html#log.detailed.core.record" title="Logging records">Logging records</a>
</h4></div></div></div>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../core_components.html#header.boost.log.core.record_hpp" title="Header &lt;boost/log/core/record.hpp&gt;">boost/log/core/record.hpp</a></code><span class="special">&gt;</span>
</pre>
<p>
          All the information that the logging library processes is packed into a
          single object of type <code class="computeroutput"><a class="link" href="../boost/log/record.html" title="Class record">record</a></code>.
          All attached data, including the message text, is represented as named
          attribute values that can be fetched and processed by filters, formatters
          and sinks. Particular attribute values can be accessed in different ways,
          here are a few quick examples:
        </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
              Through <a class="link" href="detailed/attributes.html#log.detailed.attributes.related_components.value_processing" title="Attribute value extraction and visitation">value
              visitation and extraction</a>.
            </li></ul></div>
<p>
</p>
<pre class="programlisting"><span class="keyword">enum</span> <span class="identifier">severity_level</span> <span class="special">{</span> <span class="special">...</span> <span class="special">};</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="identifier">strm</span><span class="special">,</span> <span class="identifier">severity_level</span> <span class="identifier">level</span><span class="special">);</span>

<span class="keyword">struct</span> <span class="identifier">print_visitor</span>
<span class="special">{</span>
    <span class="keyword">typedef</span> <span class="keyword">void</span> <span class="identifier">result_type</span><span class="special">;</span>
    <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">severity_level</span> <span class="identifier">level</span><span class="special">)</span> <span class="keyword">const</span>
    <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">level</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
    <span class="special">};</span>
<span class="special">};</span>

<span class="comment">// Prints severity level through visitation API</span>
<span class="keyword">void</span> <span class="identifier">print_severity_visitation</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">record</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rec</span><span class="special">)</span>
<span class="special">{</span>
    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">visit</span><span class="special">&lt;</span> <span class="identifier">severity_level</span> <span class="special">&gt;(</span><span class="string">"Severity"</span><span class="special">,</span> <span class="identifier">rec</span><span class="special">,</span> <span class="identifier">print_visitor</span><span class="special">());</span>
<span class="special">}</span>

<span class="comment">// Prints severity level through extraction API</span>
<span class="keyword">void</span> <span class="identifier">print_severity_extraction</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">record</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rec</span><span class="special">)</span>
<span class="special">{</span>
    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special">&lt;</span> <span class="identifier">severity_level</span> <span class="special">&gt;</span> <span class="identifier">level</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">extract</span><span class="special">&lt;</span> <span class="identifier">severity_level</span> <span class="special">&gt;(</span><span class="string">"Severity"</span><span class="special">,</span> <span class="identifier">rec</span><span class="special">);</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">level</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
        </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
              By searching the <a class="link" href="detailed/attributes.html#log.detailed.attributes.related_components.attribute_value_set" title="Attribute value set">set
              of attribute values</a> accessible with the <code class="computeroutput"><span class="identifier">attribute_values</span></code>
              method of the record.
            </li></ul></div>
<p>
</p>
<pre class="programlisting"><span class="comment">// Prints severity level by searching the attribute values</span>
<span class="keyword">void</span> <span class="identifier">print_severity_lookup</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">record</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rec</span><span class="special">)</span>
<span class="special">{</span>
    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_value_set</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">values</span> <span class="special">=</span> <span class="identifier">rec</span><span class="special">.</span><span class="identifier">attribute_values</span><span class="special">();</span>
    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_value_set</span><span class="special">::</span><span class="identifier">const_iterator</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">values</span><span class="special">.</span><span class="identifier">find</span><span class="special">(</span><span class="string">"Severity"</span><span class="special">);</span>
    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">it</span> <span class="special">!=</span> <span class="identifier">values</span><span class="special">.</span><span class="identifier">end</span><span class="special">())</span>
    <span class="special">{</span>
        <span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_value</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">value</span> <span class="special">=</span> <span class="identifier">it</span><span class="special">-&gt;</span><span class="identifier">second</span><span class="special">;</span>

        <span class="comment">// A single attribute value can also be visited or extracted</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">value</span><span class="special">.</span><span class="identifier">extract</span><span class="special">&lt;</span> <span class="identifier">severity_level</span> <span class="special">&gt;()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
        </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
              By applying the subscript operator with the attribute keyword. This
              is actually a convenience wrapper around the value extraction API.
            </li></ul></div>
<p>
</p>
<pre class="programlisting"><span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">severity</span><span class="special">,</span> <span class="string">"Severity"</span><span class="special">,</span> <span class="identifier">severity_level</span><span class="special">)</span>

<span class="comment">// Prints severity level by using the subscript operator</span>
<span class="keyword">void</span> <span class="identifier">print_severity_subscript</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">record</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rec</span><span class="special">)</span>
<span class="special">{</span>
    <span class="comment">// Use the attribute keyword to communicate the name and type of the value</span>
    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special">&lt;</span> <span class="identifier">severity_level</span><span class="special">,</span> <span class="identifier">tag</span><span class="special">::</span><span class="identifier">severity</span> <span class="special">&gt;</span> <span class="identifier">level</span> <span class="special">=</span> <span class="identifier">rec</span><span class="special">[</span><span class="identifier">severity</span><span class="special">];</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">level</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
        </p>
<p>
          Log records cannot be copied, only moved. A record can be default-constructed
          in which case it is in an empty state; such records are mostly unusable
          and should not be passed to the library for processing. Non-empty log records
          can only be created by the <a class="link" href="detailed.html#log.detailed.core.core" title="Logging core">logging
          core</a> as a result of successful filtering. The non-empty record contains
          attribute values acquired from attributes. More attribute values can be
          added to the non-empty record after filtering. The added values will not
          affect filtering results but can still be used by formatters and sinks.
        </p>
<p>
          In multithreaded environments, after being constructed a non-empty log
          record is considered to be tied to the current thread as it may refer to
          some thread-specific resources. For example, the record may contain an
          attribute value which refers to the named scope list which is stored on
          the stack. For this reason log records must not be passed between different
          threads.
        </p>
<h6>
<a name="log.detailed.core.record.h0"></a>
          <span class="phrase"><a name="log.detailed.core.record.record_views"></a></span><a class="link" href="detailed.html#log.detailed.core.record.record_views">Record
          views</a>
        </h6>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../core_components.html#header.boost.log.core.record_view_hpp" title="Header &lt;boost/log/core/record_view.hpp&gt;">boost/log/core/record_view.hpp</a></code><span class="special">&gt;</span>
</pre>
<p>
          While records are used for filling the information, the library uses another
          type to actually process it. Record views provide a similar interface to
          records with a few notable distinctions:
        </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
              Record views are immutable. This prevents formatters and sinks from
              modifying the record while it is being processed.
            </li>
<li class="listitem">
              Record views are copyable. Since its contents are constant, the copy
              operation is shallow and therefore cheap.
            </li>
</ul></div>
<p>
          The library will automatically create a record view from the record by
          calling the <code class="computeroutput"><span class="identifier">lock</span></code> method.
          The call will also make sure the resulting view is not attached to the
          current thread if a sink is asynchronous. The <code class="computeroutput"><span class="identifier">lock</span></code>
          call is a one time operation; the record is left in the empty state afterwards.
          All APIs for interacting with attribute values described for log records
          are also applicable to record views and can be used in custom formatters
          and sinks.
        </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="log.detailed.core.core"></a><a class="link" href="detailed.html#log.detailed.core.core" title="Logging core">Logging core</a>
</h4></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="detailed.html#log.detailed.core.core.attribute_sets">Attribute
          sets</a></span></dt>
<dt><span class="section"><a href="detailed.html#log.detailed.core.core.filtering">Global filtering</a></span></dt>
<dt><span class="section"><a href="detailed.html#log.detailed.core.core.sinks">Sink management</a></span></dt>
<dt><span class="section"><a href="detailed.html#log.detailed.core.core.exception_handling">Exception
          handling</a></span></dt>
<dt><span class="section"><a href="detailed.html#log.detailed.core.core.record_feeding">Feeding log
          records</a></span></dt>
</dl></div>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../core_components.html#header.boost.log.core.core_hpp" title="Header &lt;boost/log/core/core.hpp&gt;">boost/log/core/core.hpp</a></code><span class="special">&gt;</span>
</pre>
<p>
          The logging core is a central hub that provides the following facilities:
        </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
              Maintains global and thread-specific attribute sets.
            </li>
<li class="listitem">
              Performs global filtering of log records.
            </li>
<li class="listitem">
              Dispatches log records between sinks by applying sink-specific filters.
            </li>
<li class="listitem">
              Provides a global hook for exception handlers.
            </li>
<li class="listitem">
              Provides an entry point for log sources to put log records to.
            </li>
<li class="listitem">
              Provides the <code class="computeroutput"><span class="identifier">flush</span></code>
              method that can be used to enforce the synchronized state for all log
              sinks.
            </li>
</ul></div>
<p>
          The logging core is an application-wide singleton, thus every logging source
          has access to it. The core instance is accessible with the static method
          <code class="computeroutput"><span class="identifier">get</span></code>.
        </p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span> <span class="special">&gt;</span> <span class="identifier">core</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">();</span>

    <span class="comment">// ...</span>
<span class="special">}</span>
</pre>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<a name="log.detailed.core.core.attribute_sets"></a><a class="link" href="detailed.html#log.detailed.core.core.attribute_sets" title="Attribute sets">Attribute
          sets</a>
</h5></div></div></div>
<p>
            In order to add or remove global or thread-specific attributes to the
            core there are corresponding methods: <code class="computeroutput"><span class="identifier">add_global_attribute</span></code>,
            <code class="computeroutput"><span class="identifier">remove_global_attribute</span></code>,
            <code class="computeroutput"><span class="identifier">add_thread_attribute</span></code>
            and <code class="computeroutput"><span class="identifier">remove_thread_attribute</span></code>.
            Attribute sets provide interface similar to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span></code>,
            so the <code class="computeroutput"><span class="identifier">add_</span><span class="special">*</span></code>
            methods accept an attribute name string (key) and a pointer to the attribute
            (mapped value) and return a pair of iterator and boolean value, like
            <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span> <span class="special">...</span> <span class="special">&gt;::</span><span class="identifier">insert</span></code> does. The <code class="computeroutput"><span class="identifier">remove_</span><span class="special">*</span></code> methods accept an iterator to a previously
            added attribute.
          </p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span> <span class="special">&gt;</span> <span class="identifier">core</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">();</span>

    <span class="comment">// Add a global attribute</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_set</span><span class="special">::</span><span class="identifier">iterator</span><span class="special">,</span> <span class="keyword">bool</span> <span class="special">&gt;</span> <span class="identifier">res</span> <span class="special">=</span>
        <span class="identifier">core</span><span class="special">-&gt;</span><span class="identifier">add_global_attribute</span><span class="special">(</span><span class="string">"LineID"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">counter</span><span class="special">&lt;</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">&gt;());</span>

    <span class="comment">// ...</span>

    <span class="comment">// Remove the added attribute</span>
    <span class="identifier">core</span><span class="special">-&gt;</span><span class="identifier">remove_global_attribute</span><span class="special">(</span><span class="identifier">res</span><span class="special">.</span><span class="identifier">first</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top"><p>
              It must be said that all methods of logging core are thread-safe in
              multithreaded environments. However, that may not be true for other
              components, such as iterators or attribute sets.
            </p></td></tr>
</table></div>
<p>
            It is possible to acquire a copy of the whole attribute set (global or
            thread-specific) or install it into the core. Methods <code class="computeroutput"><span class="identifier">get_global_attributes</span></code>,
            <code class="computeroutput"><span class="identifier">set_global_attributes</span></code>,
            <code class="computeroutput"><span class="identifier">get_thread_attributes</span></code>
            and <code class="computeroutput"><span class="identifier">set_thread_attributes</span></code>
            serve this purpose.
          </p>
<div class="warning"><table border="0" summary="Warning">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../doc/src/images/warning.png"></td>
<th align="left">Warning</th>
</tr>
<tr><td align="left" valign="top"><p>
              After installing a whole attribute set into the core, all iterators
              that were previously returned by the corresponding <code class="computeroutput"><span class="identifier">add_</span><span class="special">*</span></code> methods are invalidated. In particular,
              it affects <a class="link" href="detailed/attributes.html#log.detailed.attributes.related_components.scoped_attributes" title="Scoped attributes">scoped
              attributes</a>, so the user must be careful when to switch attribute
              sets.
            </p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<a name="log.detailed.core.core.filtering"></a><a class="link" href="detailed.html#log.detailed.core.core.filtering" title="Global filtering">Global filtering</a>
</h5></div></div></div>
<p>
            Global filtering is handled by the filter function object, which can
            be provided with the <code class="computeroutput"><span class="identifier">set_filter</span></code>
            method. More on creating filters appears in <a class="link" href="detailed/expressions.html#log.detailed.expressions.predicates" title="Predicate expressions">this
            section</a>. Here it will suffice to say that the filter accepts a
            set of attribute values and returns a boolean value that tells whether
            a log record with these attribute values passed filtering or not. The
            global filter is applied to every log record made throughout the application,
            so it can be used to wipe out excessive log records quickly.
          </p>
<p>
            The global filter can be removed by the <code class="computeroutput"><span class="identifier">reset_filter</span></code>
            method. When there is no filter set in the core it is assumed that no
            records are filtered away. This is the default after initial construction
            of the logging core.
          </p>
<pre class="programlisting"><span class="keyword">enum</span> <span class="identifier">severity_level</span>
<span class="special">{</span>
    <span class="identifier">normal</span><span class="special">,</span>
    <span class="identifier">warning</span><span class="special">,</span>
    <span class="identifier">error</span><span class="special">,</span>
    <span class="identifier">critical</span>
<span class="special">};</span>

<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span> <span class="special">&gt;</span> <span class="identifier">core</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">();</span>

    <span class="comment">// Set a global filter so that only error messages are logged</span>
    <span class="identifier">core</span><span class="special">-&gt;</span><span class="identifier">set_filter</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="identifier">severity_level</span> <span class="special">&gt;(</span><span class="string">"Severity"</span><span class="special">)</span> <span class="special">&gt;=</span> <span class="identifier">error</span><span class="special">);</span>

    <span class="comment">// ...</span>
<span class="special">}</span>
</pre>
<p>
            The core also provides another way to disable logging. By calling the
            <code class="computeroutput"><span class="identifier">set_logging_enabled</span></code> with
            a boolean argument one may completely disable or re-enable logging, including
            applying filtering. Disabling logging with this method may be more beneficial
            in terms of application performance than setting a global filter that
            always fails.
          </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<a name="log.detailed.core.core.sinks"></a><a class="link" href="detailed.html#log.detailed.core.core.sinks" title="Sink management">Sink management</a>
</h5></div></div></div>
<p>
            After global filtering is applied, log sinks step into action. In order
            to add and remove sinks the core provides <code class="computeroutput"><span class="identifier">add_sink</span></code>
            and <code class="computeroutput"><span class="identifier">remove_sink</span></code> methods.
            Both these methods accept a pointer to the sink. The <code class="computeroutput"><span class="identifier">add_sink</span></code>
            will add the sink to the core if it's not added already. The <code class="computeroutput"><span class="identifier">remove_sink</span></code> method will seek for the
            provided sink in an internal list of previously added sinks and remove
            the sink if it finds it. The order in which the core processes sinks
            internally is unspecified.
          </p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span> <span class="special">&gt;</span> <span class="identifier">core</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">();</span>

    <span class="comment">// Set a sink that will write log records to the console</span>
    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_ostream_backend</span> <span class="special">&gt;</span> <span class="identifier">backend</span> <span class="special">=</span>
        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_ostream_backend</span> <span class="special">&gt;();</span>
    <span class="identifier">backend</span><span class="special">-&gt;</span><span class="identifier">add_stream</span><span class="special">(</span>
        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&gt;(&amp;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">clog</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">null_deleter</span><span class="special">()));</span>

    <span class="keyword">typedef</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">unlocked_sink</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_ostream_backend</span> <span class="special">&gt;</span> <span class="identifier">sink_t</span><span class="special">;</span>
    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">sink_t</span> <span class="special">&gt;</span> <span class="identifier">sink</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">sink_t</span> <span class="special">&gt;(</span><span class="identifier">backend</span><span class="special">);</span>
    <span class="identifier">core</span><span class="special">-&gt;</span><span class="identifier">add_sink</span><span class="special">(</span><span class="identifier">sink</span><span class="special">);</span>

    <span class="comment">// ...</span>

    <span class="comment">// Remove the sink</span>
    <span class="identifier">core</span><span class="special">-&gt;</span><span class="identifier">remove_sink</span><span class="special">(</span><span class="identifier">sink</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
            You can read more on the design of sinks in the following sections:
            <a class="link" href="detailed/sink_frontends.html" title="Sink frontends">Sink Frontends</a> and
            <a class="link" href="detailed/sink_backends.html" title="Sink backends">Sink Backends</a>.
          </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<a name="log.detailed.core.core.exception_handling"></a><a class="link" href="detailed.html#log.detailed.core.core.exception_handling" title="Exception handling">Exception
          handling</a>
</h5></div></div></div>
<p>
            The core provides a way to set up centralized exception handling. If
            an exception takes place during filtering or processing in one of the
            added sinks, the core will invoke an exception handler if one was installed
            with the <code class="computeroutput"><span class="identifier">set_exception_handler</span></code>
            method. An exception handler is a nullary function object that is invoked
            from within a <code class="computeroutput"><span class="keyword">catch</span></code> clause.
            The library provides <a class="link" href="detailed/utilities.html#log.detailed.utilities.exception_handlers" title="Exception handlers">tools</a>
            to simplify exception handlers construction.
          </p>
<div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top"><p>
              The exception handler in the logging core is global and thus is intended
              to perform some common actions on errors. Logging sinks and sources
              also provide exception handling facilities (see <a class="link" href="detailed/sink_frontends.html#log.detailed.sink_frontends.basic_services.exception_handling" title="Exception handling">here</a>
              and <a class="link" href="detailed/sources.html#log.detailed.sources.exception_handling" title="Loggers with exception handling support">here</a>),
              which can be used to do a finer grained error processing.
            </p></td></tr>
</table></div>
<p>
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">my_handler</span>
<span class="special">{</span>
    <span class="keyword">typedef</span> <span class="keyword">void</span> <span class="identifier">result_type</span><span class="special">;</span>

    <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="keyword">const</span>
    <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"std::runtime_error: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
    <span class="special">}</span>
    <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">logic_error</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="keyword">const</span>
    <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"std::logic_error: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
        <span class="keyword">throw</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">};</span>

<span class="keyword">void</span> <span class="identifier">init_exception_handler</span><span class="special">()</span>
<span class="special">{</span>
    <span class="comment">// Setup a global exception handler that will call my_handler::operator()</span>
    <span class="comment">// for the specified exception types</span>
    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">()-&gt;</span><span class="identifier">set_exception_handler</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">make_exception_handler</span><span class="special">&lt;</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span><span class="special">,</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">logic_error</span>
    <span class="special">&gt;(</span><span class="identifier">my_handler</span><span class="special">()));</span>
<span class="special">}</span>
</pre>
<p>
          </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<a name="log.detailed.core.core.record_feeding"></a><a class="link" href="detailed.html#log.detailed.core.core.record_feeding" title="Feeding log records">Feeding log
          records</a>
</h5></div></div></div>
<p>
            One of the most important functions of the logging core is providing
            an entry point for all logging sources to feed log records into. This
            is done with the <code class="computeroutput"><span class="identifier">open_record</span></code>
            and <code class="computeroutput"><span class="identifier">push_record</span></code> methods.
          </p>
<p>
            The first method is used to initiate the record logging process. It accepts
            the source-specific set of attributes. The method constructs a common
            set of attribute values of the three sets of attributes (global, thread-specific
            and source-specific) and applies filtering. If the filtering succeeded,
            i.e. at least one sink accepts a record with these attribute values,
            the method returns a non-empty <a class="link" href="detailed.html#log.detailed.core.record" title="Logging records">record
            object</a>, which can be used to fill in the log record message. If
            the filtering failed, an empty record object is returned.
          </p>
<p>
            When the log source is ready to complete the logging procedure, it has
            to call the <code class="computeroutput"><span class="identifier">push_record</span></code>
            method with the record returned by the <code class="computeroutput"><span class="identifier">open_record</span></code>
            method. Note that one should not call <code class="computeroutput"><span class="identifier">push_record</span></code>
            with an empty record. The record should be passed as rvalue reference.
            During the call the record view will be constructed from the record.
            The view will then be passed on to the sinks that accepted it during
            filtering. This may involve record formatting and further processing,
            like storing it into a file or sending it over the network. After that
            the record object can be destroyed.
          </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">logging_function</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_set</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">attrs</span><span class="special">)</span>
<span class="special">{</span>
    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span> <span class="special">&gt;</span> <span class="identifier">core</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">();</span>

    <span class="comment">// Attempt to open a log record</span>
    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">record</span> <span class="identifier">rec</span> <span class="special">=</span> <span class="identifier">core</span><span class="special">-&gt;</span><span class="identifier">open_record</span><span class="special">(</span><span class="identifier">attrs</span><span class="special">);</span>
    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">rec</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="comment">// Ok, the record is accepted. Compose the message now.</span>
        <span class="identifier">logging</span><span class="special">::</span><span class="identifier">record_ostream</span> <span class="identifier">strm</span><span class="special">(</span><span class="identifier">rec</span><span class="special">);</span>
        <span class="identifier">strm</span> <span class="special">&lt;&lt;</span> <span class="string">"Hello, World!"</span><span class="special">;</span>
        <span class="identifier">strm</span><span class="special">.</span><span class="identifier">flush</span><span class="special">();</span>

        <span class="comment">// Deliver the record to the sinks.</span>
        <span class="identifier">core</span><span class="special">-&gt;</span><span class="identifier">push_record</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">rec</span><span class="special">));</span>
    <span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
          </p>
<p>
            All this logic is usually hidden in the loggers and macros provided by
            the library. However, this may be useful for those developing new log
            sources.
          </p>
</div>
</div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2007-2021 Andrey Semashev<p>
        Distributed under the Boost Software License, Version 1.0. (See accompanying
        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>).
      </p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutorial/wide_char.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="detailed/sources.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>
